/*
 * Created on Feb 2, 2005
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package com.broadvision.manage.common.tools.action.common;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

import com.broadvision.data.client.Category;
import com.broadvision.data.client.Content;
import com.broadvision.data.common.TableData;
import com.broadvision.data.common.RowData;
import com.broadvision.data.client.DataManager;
import com.broadvision.data.common.CallSettings;
import com.broadvision.data.common.ContentUID;
import com.broadvision.data.common.DataAttributeList;
import com.broadvision.data.common.DataValue;
import com.broadvision.data.exceptions.DataException;
import com.broadvision.data.sql.SQLCompoundCondition;
import com.broadvision.data.sql.SQLCondition;
import com.broadvision.data.sql.SQLConditionFactory;
import com.broadvision.data.sql.SQLExpression;
import com.broadvision.data.sql.SQLOperator;
import com.broadvision.web.util.ViewDynaBean;
import com.broadvision.manage.tools.ToolsLog;

/**
 * @author kwlee
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class SearchCntPickerPopupAction extends BasePickerPopupAction {

  /* (non-Javadoc)
   * @see com.broadvision.portal.tools.util.BasePickerPopupAction#getList(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
   */
  public List getList(
    ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response)
    throws Exception {
     
    DynaActionForm pickerPopupForm = (DynaActionForm)form;
    List resultList = new ArrayList();    
    String searchKey = (String)PropertyUtils.getSimpleProperty(pickerPopupForm, "searchKey");
    boolean showAllCategories = ((Boolean)PropertyUtils.getSimpleProperty(pickerPopupForm, "showAllCategories")).booleanValue();
    //boolean allCategories = showAllCategories ? ((Boolean)PropertyUtils.getSimpleProperty(pickerPopupForm, "allCategories")).booleanValue() : true;
    boolean allCategories = ((Boolean)PropertyUtils.getSimpleProperty(pickerPopupForm, "allCategories")).booleanValue();
    int currentCategoryOid = ((Long)PropertyUtils.getSimpleProperty(pickerPopupForm, "currentCategoryOid")).intValue();
    boolean searchBtnNeverClicked = ((Boolean)PropertyUtils.getSimpleProperty(pickerPopupForm, "searchBtnNeverClicked")).booleanValue();
    
    int cntTypeId = Integer.parseInt((String)PropertyUtils.getSimpleProperty(pickerPopupForm, "contentTypeId"));
    String contentTypeName = DataManager.getContentTypeName(cntTypeId);
    String columnName = getColumnName(mapping, form, request, response);
    List keyNames = null;
    if (columnName != null && columnName.length() != 0) {
      keyNames = new ArrayList(1);
      keyNames.add(columnName);
    }// if
    else {
      DataAttributeList attriList = DataManager.getAttributes(cntTypeId, 
                                                              getServiceId(request));
      keyNames = attriList.getKeyNames();
    }// else
    
    if (searchBtnNeverClicked) {
      // TODO: display default search result
      long[] defaultIds = getDefaultSearchResultList(mapping, form, request, response);
      if (defaultIds.length != 0) {
        try {
          DataManager dm = new DataManager();
          CallSettings callsettings = dm.getCallSettings();
          callsettings.setFilteringFlag(false);
          ArrayList attributesList = new ArrayList(keyNames);
          attributesList.add(OID);
          resultList = 
              dm.getPartialContents(cntTypeId,getServiceId(request),
                                    defaultIds, attributesList);
        }// try
        catch (DataException ex) {
          // Do nothing and let the function return an empty array list
          System.out.println(ex.getMessage());
        }// catch
      }// if
    }
    else {
      SQLCondition allCondition = null;
      
      // Do name match only if the search key is not empty
      if (searchKey == null || searchKey.length() ==0) {
        searchKey = "%";
      }// if
      
      if (columnName != null && columnName.length() != 0) {
        allCondition = getNameMatchSqlCondition(contentTypeName,
                                                columnName,
                                                searchKey,
                                                false);
      }// if
      else {
        int count = keyNames.size();
        
        if (count == 1) {
          // if only one key
          allCondition = getNameMatchSqlCondition(contentTypeName,
                                                  (String)keyNames.get(0),
                                                  searchKey,
                                                  false);
        }// if
        else if (count > 1) {
          // If it's compound key
          allCondition = new SQLCompoundCondition(
                            getNameMatchSqlCondition(contentTypeName,
                                                    (String)keyNames.get(0),
                                                    searchKey,
                                                    false));
          for (int i = 1; i < keyNames.size(); i++) {
            SQLCondition condition = 
                          getNameMatchSqlCondition(contentTypeName,
                                                  (String)keyNames.get(i),
                                                  searchKey,
                                                  false);
            ((SQLCompoundCondition)allCondition).addCondition(SQLOperator.OP_OR,
                                                              condition);
          }// for
        }// else
        else {
          return new ArrayList();
        }// else
      }// else
      
      try {
        DataManager dm = new DataManager();
        CallSettings callsettings = dm.getCallSettings();
        callsettings.setFilteringFlag(false);
        ArrayList attributesList = new ArrayList(keyNames);
        attributesList.add(OID);
        if (allCategories) {
          resultList = 
            dm.getPartialContentsByCondition(cntTypeId, 
                                            getServiceId(request),
                                            allCondition,
                                            attributesList,
                                            false);
        }// if
        else {
          ContentUID catUid = new ContentUID(getServiceId(request), 
                                              currentCategoryOid, 
                                              contentTypeName);
          if (dm.categoryExists(catUid) == true) {
            Category cat = dm.getCategory(catUid);
            // TODO:  Should always create an attributes list and only retrieve
            //        the attributes we need.
            resultList = cat.getMemberContents(attributesList, allCondition,
                                              cntTypeId, false);
/*          Back out fix for : 44966
            String query = "SELECT A.OID, A.NAME, A.PROD_ID from BV_PRODUCT A, BV_CONTENT_REF B WHERE  ( A.OID=B.OID AND B.PARENT_OID=";
            query += cat.getOid();
            query += " AND A.DELETED=0 AND ";
            query += allCondition.toSQLString();
            query += ")";
            
            TableData result = dm.getDataByQuery(null, query);
            if(result != null && result.size() > 0) {

              for(int i=0; i < result.size(); i++ ) {

                RowData row = result.getRow(i);
                Content cnt = new Content(cntTypeId, getServiceId(request));
                cnt.setData(row);
                resultList.add(cnt);
              }
            }
*/
          }// if
        }// else          
      }// try
      catch (DataException ex) {
        // Do nothing and let the function return an empty array list
        System.out.println(ex.getMessage());
      }// catch
    }//else
    return resultList;
  }

  /* (non-Javadoc)
   * @see com.broadvision.portal.tools.util.BasePickerPopupAction#getTabPageIndex()
   */
  public int getTabPageIndex() {
    return 1;
  }
  
  public SQLCondition getNameMatchSqlCondition (String tableName, 
        String attributeName, String nameLikeStr, boolean caseSensitive) {
    if (nameLikeStr == null || nameLikeStr.length() == 0) {
        throw new IllegalArgumentException ("Parameter: nameLikeStr of SearchCntPickerPopupAction.getNameMatchSqlCondition can not be null or empty.");
    } else if (tableName == null || tableName.length() == 0) {
      throw new IllegalArgumentException ("Parameter: tableName of SearchCntPickerPopupAction.getNameMatchSqlCondition can not be null or empty.");
    } else if (attributeName == null || attributeName.length () == 0) {
      throw new IllegalArgumentException ("Parameter: attributeName of SearchCntPickerPopupAction.getNameMatchSqlCondition can not be null or empty.");
    }

    if (caseSensitive) {
      //This is a case-sensitive search
      return SQLConditionFactory.buildCondition(tableName,
              attributeName, SQLOperator.OP_LIKE,
              new DataValue("'%" + nameLikeStr + "%'"));
    }
    
    //This is a case-insensitive search
//    boolean isInformixDB = isInformix (); //Check whether db vendor is informix or not.

    //There is bug in Panama's code. If we put "upper(tableName.columnName)", it will automatically
    //extract "upper(tableName" as a table name. And put it into "from" clause of SQL statement.
    //And it will cause exception. So, we remove table name here. But this will introduce some bugs
    //if the result SQLCondition is used to generate some complicated condtion, such as join. There 
    //maybe same column names in two tables. Then we will be in trouble.
    //String fullColumnName = tableName.toUpperCase() + "." + attributeName.toUpperCase();
    String fullColumnName = attributeName.toUpperCase();

    // convert "'" into "''" in nameLikeStr
    StringBuffer processedNameLikeStr = new StringBuffer();
    for (int i = 0; i < nameLikeStr.length(); i++) {
      char currChar = nameLikeStr.charAt(i);
      processedNameLikeStr.append(currChar);
      if (currChar == '\'') 
        processedNameLikeStr.append('\'');
    }// for

    SQLExpression leftV, rightV;
    SQLOperator op;
//    if (!isInformixDB) {
      leftV = new SQLExpression ("UPPER(" + fullColumnName + ")");
      rightV = new SQLExpression ("'%" + 
                                  processedNameLikeStr.toString().toUpperCase() +
                                  "%'");
      op = SQLOperator.OP_LIKE;
//    } else {
//      //Informix doesn't support upper function
//      leftV = new SQLExpression (fullColumnName);
//      String matchString = getInformixMatchString(processedNameLikeStr.toString());
//      rightV = new SQLExpression (generateStringWithWildcard(matchString, wildCardLocation));
//      //op = SQLOperator.OP_LIKE; //We should change back to OP_MATCH after Paname put this into their latest build.
//      op = SQLOperator.OP_MATCHES; 
//    }
    SQLCondition result = new SQLCondition (leftV, op, rightV);
    return result;
  }

  /* (non-Javadoc)
   * @see com.broadvision.manage.common.tools.action.common.BasePickerPopupAction#fillUpItemBean(com.broadvision.web.util.ViewDynaBean, java.lang.Object, java.lang.String)
   */
  public void fillUpItemBean(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response,
                        ViewDynaBean viewBean, Object item, String columnName)
                                                              throws Exception {
      
    //getParentCategories()
    super.fillUpItemBean(mapping, form, request, response, viewBean, item, columnName);
  }
  
  protected long[] getDefaultSearchResultList(
    ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response)
    throws Exception {

    long[] resultList = new long[0];
    DynaActionForm pickerPopupForm = (DynaActionForm)form;
    String defaultSearchResultIds = (String)PropertyUtils.getSimpleProperty(pickerPopupForm, "defaultSearchResultIds");
    
    if (defaultSearchResultIds.length() != 0) {
      int cntTypeIdInt = Integer.parseInt((String)PropertyUtils.getSimpleProperty(pickerPopupForm, "contentTypeId"));
      StringTokenizer st = new StringTokenizer(defaultSearchResultIds, ITEM_DELIM);
      resultList = new long[st.countTokens()];
      int i = 0;
      while (st.hasMoreTokens()) {
        String token = st.nextToken();
        try {
          long id = Long.parseLong(token);
          if (isValidId(getServiceId(request), cntTypeIdInt, id));
            resultList[i++] = id;
        }// try
        catch (NumberFormatException ex) {
          continue;
        }// catch
      }// while
    }// if
    return resultList;
  }

}
